/* Copyright (C) 2024 wlly-lzh
 * Created On 24/03/06
 * Sequence List   顺序表
 *
 * */
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>

typedef struct LSqList LSqList;
struct LSqList {
	void ** Data;
	unsigned int nowLength;
	unsigned int maxLength;
};

void Error_LSqList_Null();
void Error_LSqList_Full();
void Error_LSqList_Addr();
void Error_LSqList_Malloc();
void MoveOneBehind_LSqList(LSqList *List, unsigned int addr); 
void MoveOneBefore_LSqList(LSqList *List, unsigned int addr);

LSqList * Create_LSqList(unsigned int length){
	LSqList * newList=NULL;
	newList = (LSqList *)malloc(sizeof(LSqList));
	if(newList != NULL){
		newList->Data = (void **)malloc(sizeof(void *) * length);
		if(newList->Data == NULL){
			Error_LSqList_Malloc();
			exit(3);
		}
		newList->maxLength = length;  newList->nowLength = 0;
	}else{
		Error_LSqList_Malloc();
		exit(3);
	}
	return newList;
}

bool Destroy_LSqList(LSqList **List){
	if(List != NULL && *List != NULL){
		free((*List)->Data);
		free(*List);
		*List=NULL;
		return true;
	}else{
		Error_LSqList_Null();
		exit(4);
	}
}
bool Clear_LSqList(LSqList *List){
	if(List != NULL){
		for(unsigned int i=0;i < List->nowLength; ++i){
			free(*(List->Data+i));
		}
		List->nowLength=0;
		return true;
	}else{
		Error_LSqList_Null();
		exit(4);
	}
}

bool Insert_LSqList(LSqList *List, unsigned int addr, void *Data){
	if(List == NULL){
		Error_LSqList_Null();
		exit(4);
	}
	if(Data == NULL){
		Error_LSqList_Null();
		return false;
	}
	if(List->nowLength < List->maxLength){
		if(addr > 0 && addr <= List->nowLength+1){
			MoveOneBehind_LSqList(List,addr);
			*((List->Data)+addr-1)=Data;
			List->nowLength++;
			return true;
		}else{
			Error_LSqList_Addr();
			return false;
		}
	}else{
		Error_LSqList_Full();
		return false;
	}
}

bool Update_LSqList(LSqList *List, unsigned int addr, void *Data){
	if(List == NULL){
		Error_LSqList_Null();
		exit(4);
	}
	if(Data != NULL){
		if(addr > 0 && addr <= List->nowLength){
			free(*(List->Data+addr-1));
			*(List->Data+addr-1)=Data;
			return true;
		}else{
			Error_LSqList_Addr();
			return false;
		}
	}else{
		Error_LSqList_Null();
		return false;
	}
}
bool Delete_LSqList(LSqList *List, unsigned int addr){
	if(List != NULL){
		if(addr > 0 && addr <= List->nowLength){
			free(*(List->Data+addr-1));
			MoveOneBefore_LSqList(List,addr);
			return true;
		}else{
			Error_LSqList_Addr();
			return false;
		}
	}else{
		Error_LSqList_Null();
		exit(4);
	}
}
bool IsFull_LSqList(const LSqList *List){
	if(List != NULL){
		if(List->nowLength < List->maxLength)
			return false;
		else
			return true;
	}else{
		Error_LSqList_Null();
		exit(4);
	}
}
bool IsEmpty_LSqList(const LSqList *List){
	if(List != NULL){
		if(List->nowLength == 0)
			return true;
		else
			return false;
	}else{
		Error_LSqList_Null();
		exit(4);
	}
}
unsigned int Length_LSqList(const LSqList *List){
	if(List != NULL)
		return List->nowLength;
	else{
		Error_LSqList_Null();
		exit(4);
	}
}
unsigned int MaxLength_LSqList(const LSqList *List){
	if(List != NULL)
		return List->maxLength;
	else{
		Error_LSqList_Null();
		exit(4);
	}
}
bool GetItem_LSqList(const LSqList *List,unsigned int addr,void **Data){
	if(List != NULL){
		if(addr > 0 && addr <= List->nowLength){
			*(Data)=*(List->Data+addr-1);
			return true;
		}else{
			Error_LSqList_Addr();
			return false;
		}
	}else{
		Error_LSqList_Null();
		exit(4);
	}
}
bool Locate_LSqList(const LSqList *List,void *Data,
		bool (*Compare)(const void *,const void *),unsigned int *addr){
	if(List != NULL){
		for(unsigned int i=0; i<List->nowLength; ++i){
			if((*Compare)(*(List->Data+i), Data)){
				*addr=i+1;
				return true;
			}
		}
	}else{
		Error_LSqList_Null();
		exit(4);
	}
	return false;
}
// 4
// 1 2 3 4 5 6 8 9
//       s d 
void MoveOneBehind_LSqList(LSqList *List, unsigned int addr){ //向后移动一位
	if(addr < List->nowLength)
		memmove(List->Data+addr,List->Data+addr-1,
				List->nowLength-addr);
	//for(unsigned int i=List->nowLength; i>=addr; --i){
	//	*(List->Data+i)=*(List->Data+i-1);
	//}
}
// 4
// 1 2 3 4 5 6 7 8 9
//       d s
void MoveOneBefore_LSqList(LSqList *List, unsigned int addr){
	if(addr < List->nowLength)
		memmove(List->Data+addr-1,List->Data+addr,
				List->nowLength-addr);
	//for(unsigned int i=addr-1; i<List->nowLength-1; ++i){
	//	*(List->Data+i)=*(List->Data+i+1);
	//}
}
#ifdef _LINUX_PLATFORM_
void Error_LSqList_Null(){
	fprintf(stderr,"\e[31mliblds/LSqList: Your paramete Is Null!\e[0m\n");
}
void Error_LSqList_Full(){
	fprintf(stderr,"\e[31mliblds/LSqList: The Sequence List is full!\e[0m\n");
}
void Error_LSqList_Malloc(){
	fprintf(stderr,"\e[31mliblds/LSqList: Malloc False!\e[0m\n");
}
void Error_LSqList_Addr(){
	fprintf(stderr,"\e[31mliblds/LSqList: The address is not suitable!\e[0m\n");
}
#else
void Error_LSqList_Null(){
	fprintf(stderr,"liblds/LSqList: Your paramete Is Null!\n");
}
void Error_LSqList_Full(){
	fprintf(stderr,"liblds/LSqList: The Sequence List is full!\n");
}
void Error_LSqList_Malloc(){
	fprintf(stderr,"liblds/LSqList: Malloc False!\n");
}
void Error_LSqList_Addr(){
	fprintf(stderr,"liblds/LSqList: The address is not suitable!\n");
}
#endif
